#ifndef ASYNC_H
#define ASYNC_H

#include <functional>
#include <QThread>
#include <QCoreApplication>
#include <QVariant>

class QAsync
{
public:
    static void onMain(std::function<void()>&& asyncCall)
    {
        onThread(QCoreApplication::instance()->thread(), std::forward<std::function<void()>>(asyncCall));
    }

    static void onThread(QThread* thread, std::function<void()>&& asyncCall)
    {
        static const char* contextProperty = ("qasync-context");
        auto obj = thread->property(contextProperty).value<QObject*>();
        if (!obj)
        {
            obj = new QObject(thread);
            obj->moveToThread(thread);
            thread->setProperty(contextProperty, QVariant::fromValue(obj));
        }
        QMetaObject::invokeMethod(obj, std::forward<std::function<void()>>(asyncCall), Qt::QueuedConnection);
    }
    };

#endif // ASYNC_H
